package com.gksc.jcef;

import com.gksc.jcef.constant.BusinessConstant;
import com.gksc.jcef.ui.CustomTipDialog;
import com.gksc.jcef.util.Tool;
import org.cef.CefApp;
import org.cef.CefApp.CefAppState;
import org.cef.CefClient;
import org.cef.CefSettings;
import org.cef.browser.CefBrowser;
import org.cef.browser.CefFrame;
import org.cef.handler.CefAppHandlerAdapter;
import org.cef.handler.CefDisplayHandlerAdapter;
import org.cef.handler.CefFocusHandlerAdapter;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.URL;

/**
 * @ClassName: ChromeFrame
 * @Description: 内嵌Google浏览器访问页面-入口
 * @author: Liao.yx
 * @date: 2021年5月27日16:16:47
 * @copyRight: 2020 liaoyongxiang All rights reserved.
 */
public class ChromeFrame extends JFrame {
    /**
     * 定制栏控件
     */
    private JTextField address;
    /**
     * cef-app应用
     */
    private CefApp app;
    /**
     * cef-client对象
     */
    private CefClient client;
    /**
     * cef-browser对象
     */
    private CefBrowser browser;
    /**
     * 浏览器组件
     */
    private Component browserUI;
    /**
     * 浏览器是否获取焦点
     */
    private boolean browserFocus = true;

    /**
     * @param appName       应用名称
     * @param icon          应用图标
     * @param width         宽度
     * @param height        高度
     * @param posX          横坐标
     * @param posY          纵坐标
     * @param startURL      浏览器访问路径
     * @param useOSR        是否Linux系统
     * @param isTransparent 是否透明
     * @param isShowAddr    是否展示浏览器地址栏
     * @param isCloseExit   是否关闭时退出程序
     * @param isChangeSize  是否可以改变大小
     */
    public void create(String appName, String icon, int width, int height, int posX, int posY, String startURL, String logPath, boolean useOSR,
                       boolean isTransparent, boolean isShowAddr, boolean isCloseExit, boolean isChangeSize) {
        this.setTitle(Tool.isEmpty(appName) ? "java集成cef测试程序" : appName);
        URL resource = this.getClass().getClassLoader().getResource(Tool.isEmpty(appName) ? "logo.jpg" : icon);
        ImageIcon image = new ImageIcon(resource);
        this.setIconImage(image.getImage());
        this.setUndecorated(false);//去处边框
        this.setAlwaysOnTop(true);//总在最前面
        this.setResizable(isChangeSize);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        CefApp.addAppHandler(new CefAppHandlerAdapter(null) {
            @Override
            public void stateHasChanged(CefAppState state) {
                // 如果本机 CEF 部分终止，则关闭应用程序
                if (state == CefAppState.TERMINATED) {
                    System.exit(0);
                }
            }
        });
        CefSettings settings = new CefSettings();
        settings.log_file = Tool.isEmpty(logPath) ? "c:\\cef.log" : logPath;
        settings.windowless_rendering_enabled = useOSR;
        app = CefApp.getInstance(settings);
        client = app.createClient();
        browser = client.createBrowser(startURL, useOSR, isTransparent);
        browserUI = browser.getUIComponent();
        address = new JTextField(startURL, 100);
        address.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                browser.loadURL(address.getText());
            }
        });
        client.addDisplayHandler(new CefDisplayHandlerAdapter() {
            @Override
            public void onAddressChange(CefBrowser browser, CefFrame frame, String url) {
                address.setText(url);
            }
        });

        address.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                if (!browserFocus) return;
                browserFocus = false;
                KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
                address.requestFocus();
            }
        });
        client.addFocusHandler(new CefFocusHandlerAdapter() {
            @Override
            public void onGotFocus(CefBrowser browser) {
                if (browserFocus) return;
                browserFocus = true;
                KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
                browser.setFocus(true);
            }

            @Override
            public void onTakeFocus(CefBrowser browser, boolean next) {
                browserFocus = false;
            }
        });
        if (isShowAddr) {
            getContentPane().add(address, BorderLayout.NORTH);
            getContentPane().add(browserUI, BorderLayout.CENTER);
        } else {
            getContentPane().add(browserUI);
        }
        pack();
        if (width > 0 && height > 0) {
            this.setSize(width, height);
        } else {
            width = BusinessConstant.width;
            height = BusinessConstant.height;
            this.setSize(width, height);
        }
        if (posX > 0 && posY > 0) {
            this.setLocation(posX, posY);
        } else {
            Toolkit toolkit = Toolkit.getDefaultToolkit();
            posX = (int) (toolkit.getScreenSize().getWidth() - this.getWidth()) / 2;
            posY = (int) (toolkit.getScreenSize().getHeight() - this.getHeight()) / 2;
            this.setLocation(posX, posY);
        }
        this.setVisible(true);

        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                if (isCloseExit) {
                    System.exit(1);
                } else {
                    setVisible(false);
                }
            }
        });
    }

    public ChromeFrame(String startURL, boolean useOSR, boolean isTransparent) {
        create(null, null, BusinessConstant.width, BusinessConstant.height, 0, 0, startURL, null, useOSR, isTransparent, true, true, true);
    }

    public ChromeFrame(String appName, String icon, int width, int height, int posX, int posY, String startURL, String logPath, boolean useOSR,
                       boolean isTransparent, boolean isShowAddr, boolean isCloseExit, boolean isChangeSize) {
        create(appName, icon, width, height, posX, posY, startURL, logPath, useOSR, isTransparent, isShowAddr, isCloseExit, isChangeSize);
    }

    public CefClient getClient() {
        return client;
    }

    public static void main(String[] args) {
        if (!CefApp.startup()) {
            System.out.println("Startup initialization failed!");
            return;
        }

        ChromeFrame main = new ChromeFrame("http://www.baidu.com/", false, false);
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
        }

        CustomTipDialog tip = new CustomTipDialog(main, "是否确定删除该数据？", "删除用户信息", "", JOptionPane.INFORMATION_MESSAGE, JOptionPane.YES_NO_OPTION);
        if (tip.call() == JOptionPane.OK_OPTION) {
            System.out.println("用户操作成功");
        } else {
            System.err.println("用户操作失败");
        }
    }
}
